parser grammar CommonParser;

options {
    language=CSharp;
    tokenVocab = CommonLexer;
}

@lexer::namespace {
    Common.Grammar.Antlr
}

expression
    :   expression_primary                                                              # expression_atom
    |   TOKEN_OP_LPARENT expression TOKEN_OP_RPARENT                                    # expression_parentheses
    |   expression bop=TOKEN_OP_CARET expression                                        # expression_caret
    |   expression bop=(TOKEN_OP_STAR | TOKEN_OP_SLASH | TOKEN_OP_MODULUS) expression   # expression_multiplicative
    |   expression bop=(TOKEN_OP_PLUS | TOKEN_OP_DASH) expression                       # expression_additive
    |   expression bop=(
            TOKEN_OP_GT |
            TOKEN_OP_LT |
            TOKEN_OP_GE |
            TOKEN_OP_LE |
            TOKEN_OP_BANGEQ |
            TOKEN_OP_VERSUS |
            TOKEN_OP_EITHER |
            TOKEN_OP_EQUALEQUAL
        ) expression                                                                    # expression_relational
    |   expression bop=(TOKEN_OP_AND | TOKEN_OP_OR) expression                          # expression_andor
    |   expression TOKEN_OP_QUES expression TOKEN_OP_COLON expression                   # expression_ternary
    |   TOKEN_OP_BANG expression                                                        # expression_not
    |   prefix=(TOKEN_OP_PLUS | TOKEN_OP_DASH) expression                               # expression_unitary
    |   TOKEN_IDENTIFIER                                                                # identifier
    ;
     
expression_primary
    :   TOKEN_OP_LPARENT expression_primary TOKEN_OP_RPARENT
    |   expression_new
    |   expression_other_function
    |   literal
    ;

expression_new
    :   TOKEN_KEY_NEW TOKEN_OP_LBRACE expression_new_props TOKEN_OP_RBRACE
    ;

expression_new_props
    :   expression_assign (TOKEN_OP_COMMA expression_assign)*
    ;

expression_assign
    :   TOKEN_IDENTIFIER TOKEN_OP_EQUAL expression
    ;

expression_other_function
    :   TOKEN_IDENTIFIER TOKEN_OP_LPARENT expression_list TOKEN_OP_RPARENT
	;

expression_list
    :   TOKEN_OP_LPARENT expression_list TOKEN_OP_RPARENT
    |   expression? (TOKEN_OP_COMMA (expression))*
	;

literal
    :   TOKEN_CONST_INTEGER
    |   TOKEN_CONST_FLOAT
    |   TOKEN_CONST_DECIMAL
    |   TOKEN_CONST_DOUBLE
    |   TOKEN_CONST_STRING
    |   TOKEN_KEY_TRUE
    |   TOKEN_KEY_FALSE
    |   TOKEN_CONST_TIME
    |   TOKEN_CONST_DATE
    ;